<template>
  <view class="tv-scroll-view">
    <scroll-view id="scroll" :style="{ width, height }" :scroll-x="scrollX" :scroll-y="scrollY" :scroll-top="scrollTop" :scroll-left="scrollLeft" :lower-threshold="lowerThreshold" @scroll="scroll" @scrolltolower="scrolltolower">
      <view class="tv-scroll-view__content">
        <slot></slot>
      </view>
    </scroll-view>
  </view>
</template>

<script>
  /**
   * tv-scroll-view 可滚动视图区域
   * @description 类似于scroll-view，用于区域滚动，需要在tv-page内使用
   * @property { width } 宽度, scroll-x为true时必须设置
   * @property { height } 高度, scroll-y为true时必须设置
   * @property { scrollX } 允许横向滚动
   * @property { scrollY } 允许纵向滚动
   * @property { lowerThreshold } 距底部/右边多远时（单位px），触发 scrolltolower 事件，默认值50
   * @event { scroll } 滚动时触发
   * @event { scrolltolower } 滚动到底部/右边，会触发 scrolltolower 事件
   */
  import mixin from '../../mixin/mixin.js';

  export default {
    mixins: [mixin],
    props: {
      // 宽度
      width: {
        type: String,
        default: 'auto'
      },
      // 高度
      height: {
        type: String,
        default: 'auto'
      },
      // 允许横向滚动
      scrollX: {
        type: Boolean,
        default: false
      },
      // 允许纵向滚动
      scrollY: {
        type: Boolean,
        default: false
      },
      // 距底部/右边多远时（单位px），触发 scrolltolower 事件
      lowerThreshold: {
        type: Number,
        default: 50
      }
    },
    inject: ['tvProps', 'areaUid'],
    data: () => ({
      scrollTop: 0,
      scrollLeft: 0,
      tvState: {}
    }),
    watch: {
      'tvState.index': {
        immediate: true,
        handler(val) {
          this.tvState.tvViews && this.tvState.tvViews.length && this.$nextTick(() => { this.viewKeyMove(val); });
        }
      }
    },
    methods: {
      // 焦点移动，使当前焦点元素尽可能在中心位置
      async viewKeyMove(index) {
        const scrollInfo = await this.$getRect('#scroll');
        const viewInfo = await this.$getRect(`.tv-view${this.tvState.tvViews[index]._uid}`);
        if (this.scrollX) {
          if (['left', 'right'].includes(this.tvProps.keyType)) {
            if (viewInfo.right > scrollInfo.right || viewInfo.left < 0) {
              this.scrollLeft += viewInfo.left - (scrollInfo.width / 2) + (viewInfo.width / 2);
            }
          }
        }
        if (this.scrollY) {
          if (['up', 'down'].includes(this.tvProps.keyType)) {
            if (viewInfo.bottom > scrollInfo.bottom || viewInfo.top < 0) {
              this.scrollTop += viewInfo.top - (scrollInfo.height / 2) + (viewInfo.height / 2);
            }
          }
        }
      },
      // 滚动
      scroll(e) {
        this.updateRect();
        this.$emit('scroll', e);
      },
      // 滚动到底部/右边
      scrolltolower(e) {
        this.$emit('scrolltolower', e);
      },
      // 更新元素布局信息
      updateRect() {
        this.tvState.tvViews && this.tvState.tvViews.forEach(v => v.updateRect());
      }
    },
    created() {
      this.tvState = this.tvProps.tvFocus.find(v => v.uid === this.areaUid);
    }
  };
</script>

<style lang="scss" scoped>
.tv-scroll-view {
  &__content {
    position: relative;
    width: 100%;
    height: 100%;
  }
}
</style>
